<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>canvas 模拟光的反射</title>
</head>
<body>
	<canvas id="canvas" width="1000" height="600" style="border:1px yellow solid;">
	
	</canvas>
<script>
    //定义弧长
    var Hd = function(x,y,r,xrange,yrange){
    	this.x = x;
    	this.y = y;
    	this.r = r;
    	this.xrange = xrange; //return true 校验通过 ， false 校验未通过
    	this.yrange = yrange; //return true 校验通过 ， false 校验未通过
    	return this;
    }
    Hd.prototype.focusPoint = function(line){
    	var preResult = this._focusPoint(line);
    	var result = [];
    	debugger;
    	for(var i =0 ;i<preResult.length;i++){
    		var p = preResult[i];
    		var valid = true;
    		if (this.xrange&&!this.xrange(p.x)) {
    			valid = false;
    		}
    		if (this.yrange&&!this.yrange(p.y)) {
    			valid = false;
    		}
    		if(valid){
    			result.push(p);
    		}
    	}
    	return result;
    }
    //求直线与圆的焦点
    Hd.prototype._focusPoint = function(line){
    	var lineSin = Math.sin(line.sita);
    	var lineCos = Math.cos(line.sita);

    	if (lineCos==1) {
    		// lineCos = 1 & sin(sita)*x-cos(sita)*y+k=0 => y = k;

    		//设 圆方程为 (x-x0)^2+(y-y0)^2 = r^2 => 圆方程为 (x-x0)^2+(k-y0)^2 = r^2

    		//=> x^2-2*x0*x+x0^2+(k-y0)^2-r^2 = 0 => a=1 b=-2*x0 c=x0^2+(k-y0)^2-r^2
    		var x0 = this.x , y0 = this.y , r = this.r , k = line.k;

    		var a = 1 , b = -2*x0 , c = Math.pow(x0,2)+Math.pow((k-y0),2)-Math.pow(r,2);

    		var result = this.qiu2result(a,b,c);
    		if(result.length==0){
    			return [];
    		}
    		if(result.length==1){
    			var x = result[0];
    			return [{x:x,y:k}];
    		}
    		if(result.length==2){
    			var x = result[0];
    			var x1 = result[1];
    			return [{x:x,y:k},{x:x1,y:k}];
    		}
    	}
    	if(lineSin==1){
    		// lineSin = 1 & sin(sita)*x-cos(sita)*y+k=0 => x+k = 0; x=-k
    		// 设 圆方程为 (x-x0)^2+(y-y0)^2 = r^2 => (k+x0)^2+(y-y0)^2 = r^2
    		// => a=1 b=-2*y0 c=(k+x0)^2+y0^2-r^2
    		var x0 = this.x , y0 = this.y , r = this.r , k = line.k;

    		var a = 1 , b = -2*y0 , c = Math.pow((k+x0),2)+Math.pow(y0,2)-Math.pow(r,2);

    		var result = this.qiu2result(a,b,c);
    		if(result.length==0){
    			return [];
    		}
    		if(result.length==1){
    			var y = result[0];
    			return [{x:-1*k,y:y}];
    		}
    		if(result.length==2){
    			var y = result[0];
    			var y1 = result[1];
    			return [{x:-1*k,y:y},{x:-1*k,y:y1}];
    		}
    	}

    	//直线点斜式：y = lineSin/lineCos*x +k/lineCos 带入 直线方程中
    	return _dx_focusPoint(this.x,this.y,this.r,lineSin/lineCos,k/lineCos);
    }

    Hd.prototype._dx_focusPoint = function(x0,y0,r,p,q){
    	//圆的参数x0,y0,r 直线的参数p,q
    	/**
			设 圆方程为 (x-x0)^2+(y-y0)^2 = r^2   直线方程为 y = px+q   t = q-y0(t为常量)

			=>  (x-x0)^2+(px+q-y0)^2 = r^2  => (x-x0)^2+(px+t)^2 = r^2  => a=1+p^2 , b=-2*x0-2*p*t , c= x0^2+t^2-r^2

			求出deta = b^2-4*a*c

				detakg = 更号 (deta)

			求出

			x1 = (-1*b + detakg) / (2*a)

			x2 = (-1*b - detakg) / (2*a)

			带入直线方程可求出y1 y2
    	*/
    	var t = q-y0;
    	var a = 1+Math.pow(p,2);
    	var b = -2*x0-2*p*t;
    	var c = Math.pow(x0,2)+Math.pow(t,2)-Math.pow(r,2);
    	var results = this.qiu2result(a,b,c);
    	if(result.length==0){
    		return [];
    	}
    	if(result.length==1){
    		var x = result[0];
    		var y = p*x+q;
    		return [{x,y}];
    	}
    	if(result.length==2){
    		var x1 = result[0];
    		var x2 = result[1];
    		var y1 = p*x1+q;
    	    var y2 = p*x2+q;
    		return [{x:x1,y:y1},{x:x2,y:y2}];
    	}
    }

    Hd.prototype.qiu2result = function(a,b,c){
    	//二次方程求解
    	    	var deta = Math.pow(b,2)-4*a*c;
    	if(deta<0){
    		return [];
    	}
    	var detakg = Math.sqrt(deta);
    	if(deta==0){
			var x1 = (-1*b + detakg) / (2*a);
			return [x1];
    	}
    	var x1 = (-1*b + detakg) / (2*a);
    	var x2 = (-1*b - detakg) / (2*a);
    	return [x1,x2];
    }
    Hd.prototype.qieLine = function(x,y){ //关于 切点(x,y) 的切线
    	// 求切线角B
    	// 更号 x^2+y^2
    	var r = this.r; 
    	var sinA = y/r;
    	var cosA = x/r;
    	var A = 0;
    	var B = 0;
		if(x>0&&y>0){
    		A = Math.asin(sinA)+Math.PI/2;
		}
		if(y>0&&x<0){
			B = Math.PI-Math.asin(sinA);
		}
		if(y<0&&x<0){
			B = Math.PI+Math.asin(sinA);
		}
		if(y<0&&x>0){
			B = 
		}

    }

    //定义直线 sin(sita)*x-cos(sita)*y+k=0
    var Line = function(sita,x,y,xrange,yrange){
    	this.sita = sita;
    	this.k = Math.cos(sita)*y-Math.sin(sita)*x;
    	this.xrange = xrange; //return true 校验通过 ， false 校验未通过
    	this.yrange = yrange; //return true 校验通过 ， false 校验未通过
    	return this;
    }
    Line.prototype.fs = function(fsmLine){ //传入反射面直线
    	var beita = 2*fsmLine.sita - this.sita;
    	//求焦点  设： a*x+b*y+c = 0 & p*x+q*y+t=0  =>  y=(a*t-p*c)/(p*b-q*a) x=-(q*y+t)/p

    	var a = Math.sin(this.sita);
    	var b = Math.cos(this.sita);
    	var c = this.k;

    	var p = Math.sin(fsmLine.sita);
    	var q = Math.cos(fsmLine.sita);
    	var t = fsmLine.sita;

    	var y = (a*t-p*c)/(p*b-q*a);
    	var x = -(q*y+t)/p;

    	// k = cos(sita)*y-sin(sita)*x
    	k = cos(beita)*y+sin(beita)*x;
    	line = new Line(beita,k);
    	return line;
    }
    Line.prototype.y = function(x){
    	// a*x+b*y+c=0 => y = -1*(a*x+c) / b
    	var a = Math.sin(this.sita);
    	var b = -1*Math.cos(this.sita);
    	var c = this.k;
    	if(b==0){
    		return;
    	}
    	return -1*(a*x+c) / b;
    }
    Line.prototype.x = function(y){
    	// x = -1*(b*y+c)/a
    	var a = Math.sin(this.sita);
    	var b = -1*Math.cos(this.sita);
    	var c = this.k;
    	if(a==0){
    		return;
    	}
    	return -1*(b*y+c)/a ;
    }

    // 以下包含的方程  (x-500)^2+(y-480)^2=450^2 
    //  sin(3*PI/4)x-cos(3*PI/4)=K( 经过 leftPointX ,leftPointY)
    //  y=leftPointY+45 
    //  sin0-cos0=K2 (经过 rightPointX,rightPointY)
	x = 500;
	y = 480;
	r = 450;

	var leftPointX = x-r;
	var leftPointY = y;
	var rightPointX = x+r;
	var rightPointY = y;

	var canvas = document.getElementById("canvas");
	var c = canvas.getContext("2d");

	//设置样式
    c.lineWidth = 1;
    c.strokeStyle = "#F5270B";


	c.arc(x,y,r,0,Math.PI,true);


    //绘制
    c.stroke();

	
	var rsLight = new Line(Math.PI/2,rightPointX-45,rightPointY+45,function(x){
		return true;
	},
	function(y){
		if(y<(rightPointY+45)){
			return true;
		}else{
			return false;
		}
	}
	);
	// debugger;
	// c.moveTo(rightPointX-45,rightPointY+45);
	// c.lineTo(rsLight.x(20),20)
 // 	//绘制
 //    c.stroke();


	var hd = new Hd(x,y,r,null,function(y){
		if(y<=480){
			return true;	
		}else{
			return false;
		}
	})
	debugger;
	var fp = hd.focusPoint(rsLight);
	c.moveTo(rightPointX-45,rightPointY+45);
	c.lineTo(fp[0].x,fp[0].y);

	c.stroke();

</script>

</body>
</html>